<?php

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\console\input\Argument;
use think\facade\App;
use think\facade\Db;

class MakeValidate extends Command
{
    protected function configure()
    {
        $this->setName('make:validate')
            ->addArgument('name', Argument::REQUIRED, '验证器名称（对应数据库表名）')
            ->addOption('extend', null, Option::VALUE_REQUIRED, '继承的父类')
            ->addOption('module', null, Option::VALUE_REQUIRED, '模块名称，默认为 app');
    }

    protected function execute(Input $input, Output $output)
    {
        $name = ucfirst($input->getArgument('name'));
        $extendClass = $input->getOption('extend') ?: 'Validate';
        $module = $input->getOption('module');

        // 获取模板路径
        $stubPath = App::getAppPath() . 'command' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . 'validate.tpl';

        if (!file_exists($stubPath)) {
            $output->writeln("<error>验证器模板文件不存在</error>");
            return;
        }

        $content = file_get_contents($stubPath);
        $tableName = strtolower($name);
        // 获取数据库字段列表
        try {
            $fields = Db::query("SHOW FULL COLUMNS FROM {$tableName}");
        } catch (\Exception $e) {
            $output->writeln("<error>无法获取表 {$tableName} 的字段信息</error>");
            return;
        }

        // 构建验证规则
        $rules = [];
        $messages = [];

        // 构建验证规则
        foreach ($fields as $field) {
            $fieldName = $field['Field'];
            $type = strtolower($field['Type']);
            $isNull = $field['Null'] === 'NO'; // 字段是否非空
            $comment = $field['Comment'] ?: $fieldName;

            $rule = '';
            if (strpos($type, 'int') !== false || strpos($type, 'bigint') !== false) {
                $rule = "'{$fieldName}' => '" . ($isNull ? 'require|' : '') . "number'";
            } elseif (strpos($type, 'varchar') !== false || strpos($type, 'char') !== false) {
                $length = preg_match('/\((\d+)\)/', $type, $matches) ? $matches[1] : 255;
                $rule = "'{$fieldName}' => '" . ($isNull ? 'require|' : '') . "max:{$length}'";
            } elseif (strpos($type, 'text') !== false) {
                $rule = "'{$fieldName}' => '" . ($isNull ? 'require|' : '') . "string'";
            } elseif (strpos($type, 'datetime') !== false || strpos($type, 'date') !== false) {
                $rule = "'{$fieldName}' => '" . ($isNull ? 'require|' : '') . "date'";
            } else {
                $rule = "'{$fieldName}' => ''";
            }

            $rules[] = $rule;

            // 构建 message
            $messages[] = "'{$fieldName}.require' => '请输入{$comment}'";
            $messages[] = "'{$fieldName}.number' => '{$comment}必须是数字'";
            $messages[] = "'{$fieldName}.max' => '{$comment}不能超过最大长度'";
            $messages[] = "'{$fieldName}.date' => '{$comment}格式不正确'";
        }

        $rulesStr = implode(",\n        ", $rules);
        $messagesStr = implode(",\n        ", $messages);

        // 修改：处理 module 为空的情况
        $namespace = $module ? "app\\{$module}\\validate" : "app\\validate";

        // 替换变量
        $content = str_replace(
            ['{{className}}', '{{extendClass}}', '{{rules}}', '{{messages}}', '{{namespace}}'],
            [$name, $extendClass, $rulesStr, $messagesStr, $namespace],
            $content
        );

        // 写入目标文件
        $validatePath = app_path() . "{$module}/validate/{$name}.php";
        if (!is_dir(dirname($validatePath))) {
            mkdir(dirname($validatePath), 0755, true);
        }
        file_put_contents($validatePath, $content);

        $output->writeln("验证器 {$name} 已生成，继承自 {$extendClass}，位于模块 {$module}");
    }
}
